home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib43 / mntlib / sigactio.c < prev    next >
C/C++ Source or Header  |  1993-09-22  |  5KB  |  236 lines

  1. /* sigaction() and sigset functions for MiNT; placed in the public domain */
  2.  
  3. #include <errno.h>
  4. #include <osbind.h>
  5. #include <mintbind.h>
  6. #include <signal.h>
  7.  
  8. /* vector of signal handlers (for TOS, or for MiNT with -mshort) */
  9. extern __Sigfunc _sig_handler[__NSIG];
  10.  
  11. #ifdef __MSHORT__
  12. typedef void __CDECL (*__KerSigfunc) __PROTO((long, long));
  13. __EXTERN void __CDECL _trampoline __PROTO((long sig, long code));
  14. #else
  15. typedef void __CDECL (*__KerSigfunc) __PROTO((int));
  16. #endif
  17.  
  18. int
  19. sigaction(sig, act, oact)
  20.     int sig;
  21.     const struct sigaction *act;
  22.     struct sigaction *oact;
  23. {
  24.     long r;
  25.     extern int __mint;
  26.     __Sigfunc oldfunc;
  27.  
  28.     if (__mint >= 95) {
  29.         struct ksigact {
  30.             __KerSigfunc    sa_handler;    /* pointer to signal handler */
  31.             long        sa_mask;    /* additional signals masked during delivery */
  32.             short        sa_flags;    /* signal specific flags, kernel */
  33.         } kact, koact;
  34.  
  35.         if (sig < 0 || sig >= __NSIG) {
  36.             errno = ERANGE;
  37.             return -1;
  38.         }
  39.  
  40. #ifdef __MSHORT__
  41. /* NOTE: MiNT passes 32 bit numbers for signals, so we want our
  42.  * own signal dispatcher to switch these to 16 bit ints
  43.  */
  44.         oldfunc = _sig_handler[sig];
  45. #endif
  46.         if (act) {
  47.             kact.sa_handler = (__KerSigfunc) act->sa_handler;
  48.             kact.sa_mask = act->sa_mask.__sigset_data[0];
  49.             kact.sa_flags = (short) act->sa_flags;
  50. #ifdef __MSHORT__
  51.             _sig_handler[sig] = (__Sigfunc)kact.sa_handler;
  52.             if (_sig_handler[sig] != SIG_DFL && _sig_handler[sig] != SIG_IGN) {
  53.                 kact.sa_handler = _trampoline;
  54.             }
  55. #endif
  56.         }
  57.         r = Psigaction(sig, (act ? &kact : 0L), (oact ? &koact : 0L));
  58.         if (r < 0) {
  59.             errno = (int) -r;
  60.             return -1;
  61.         }
  62.         if (oact) {
  63.             oact->sa_mask.__sigset_data[0] = koact.sa_mask;
  64.             oact->sa_flags = (int) koact.sa_flags;
  65. #ifdef __MSHORT__
  66.             oact->sa_handler =
  67.               ((koact.sa_handler == (__KerSigfunc) _trampoline)
  68.                ? oldfunc
  69.                : (__Sigfunc) koact.sa_handler);
  70. #else
  71.             oact->sa_handler = (__Sigfunc) koact.sa_handler;
  72. #endif
  73.         }
  74.     }
  75.     else {
  76.         if (act)
  77.             oldfunc = signal(sig, act->sa_handler);
  78.         else {
  79.             long omask;
  80.  
  81.             omask = sigblock(sig);
  82.             oldfunc = signal(sig, SIG_DFL);
  83.             signal(sig, oldfunc);    /* need to put it back */
  84.             sigsetmask(omask);    /* may remask sig (this is what we want) */
  85.         }
  86.         if (oldfunc == SIG_ERR)
  87.             return -1;
  88.         if (oact) {
  89.             oact->sa_handler = oldfunc;
  90.             /* we could do something useful with sa_mask when __mint */
  91.             oact->sa_flags = 0;
  92.             oact->sa_mask.__sigset_data[0] = 0;
  93.         }
  94.     }
  95.     return 0;
  96. }
  97.  
  98. int
  99. sigaddset(set, signo)
  100.   sigset_t *set;
  101.   int signo;
  102. {
  103.   int idx;
  104.   int pos;
  105.  
  106.   if ((!set) || (signo >= __NSIG)) {
  107.     errno = EINVAL;
  108.     return -1;
  109.   }
  110.   idx = _SIGSET_INDEX(signo);
  111.   pos = _SIGSET_BITPOS(signo);
  112.   set->__sigset_data[idx] |= sigmask(pos);
  113.   return 0;  
  114. }
  115.  
  116. int
  117. sigdelset(set, signo)
  118.   sigset_t *set;
  119.   int signo;
  120. {
  121.   int idx;
  122.   int pos;
  123.  
  124.   if ((!set) || (signo >= __NSIG)) {
  125.     errno = EINVAL;
  126.     return -1;
  127.   }
  128.   idx = _SIGSET_INDEX(signo);
  129.   pos = _SIGSET_BITPOS(signo);
  130.   set->__sigset_data[idx] &= ~(sigmask(pos));
  131.   return 0;  
  132. }
  133.  
  134. int
  135. sigemptyset(set)
  136.   sigset_t *set;
  137. {
  138.   int idx;
  139.  
  140.   if (!set) {
  141.     errno = EINVAL;
  142.     return -1;
  143.   }
  144.   for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
  145.     set->__sigset_data[idx] = 0UL;
  146.   }
  147.   return 0;  
  148. }
  149.  
  150. int
  151. sigfillset(set)
  152.   sigset_t *set;
  153. {
  154.   int idx;
  155.  
  156.   if (!set) {
  157.     errno = EINVAL;
  158.     return -1;
  159.   }
  160.   for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
  161.     set->__sigset_data[idx] = ~0UL;
  162.   }
  163.   return 0;  
  164. }
  165.  
  166. int
  167. sigismember(set, signo)
  168.   sigset_t *set;
  169.   int signo;
  170. {
  171.   int idx;
  172.   int pos;
  173.  
  174.   if ((!set) || (signo >= __NSIG)) {
  175.     errno = EINVAL;
  176.     return -1;
  177.   }
  178.   idx = _SIGSET_INDEX(signo);
  179.   pos = _SIGSET_BITPOS(signo);
  180.   return (set->__sigset_data[idx] & sigmask(pos)) ? 1 : 0;
  181. }
  182.  
  183. int
  184. sigpending(set)
  185.   sigset_t *set;
  186. {
  187.   if (!set) {
  188.     errno = EINVAL;
  189.     return -1;
  190.   }
  191.   (void) sigemptyset(set);
  192.   set->__sigset_data[0] = Psigpending();
  193.   return 0;
  194. }
  195.  
  196. int
  197. sigprocmask(how, set, oset)
  198.   int how;
  199.   const sigset_t *set;
  200.   sigset_t *oset;
  201. {
  202.   int rv = 0;
  203.   long omask = 0L;
  204.  
  205.   if (!set) {
  206.     errno = EINVAL;
  207.     return -1;
  208.   }
  209.   switch (how) {
  210.     case SIG_BLOCK:
  211.       omask = Psigblock(set->__sigset_data[0]);
  212.       break;
  213.     case SIG_UNBLOCK:
  214.       omask = Psigblock(0L);
  215.       (void) Psigsetmask(omask & ~(set->__sigset_data[0]));
  216.       break;
  217.     case SIG_SETMASK:
  218.       omask = Psigsetmask(set->__sigset_data[0]);
  219.       break;
  220.     default:
  221.       errno = EINVAL;
  222.       rv = -1;
  223.   }
  224.   if (oset) oset->__sigset_data[0] = omask;
  225.   return rv;
  226. }
  227.  
  228. int
  229. sigsuspend(signalmask)
  230.   const sigset_t *signalmask;
  231. {
  232.   Psigpause(signalmask->__sigset_data[0]);
  233.   errno = EINTR;
  234.   return -1;
  235. }
  236.